package com.self.ry.config.redis;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

import java.util.concurrent.CountDownLatch;

/**
 * Copyright: Copyright (c) 2019
 *
 * @Description: Redis发布订阅模式示例
 *
 * 1. 创建连接工厂
 * 2. 创建消息监听容器
 * 3. 创建RedisTemplate
 *
 * @Version: v1.0.0
 * @Author ruyi
 * @Date 2019/6/28 9:28
 */
//@Configuration
public class RedisExample {

    /**
     * 创建 消息监听适配器
     * @param receiver
     * @return
     */
    @Bean
    MessageListenerAdapter listenerAdapter(Receiver receiver) {

        // 使用给定的代理类创建一个MessageListenerAdapter
        // 参数1：代理类
        // 参数2：代理类中的public方法
        return new MessageListenerAdapter(receiver, "receiveMessage");
    }

    /**
     * 创建 消息监听容器
     * @param connectionFactory  连接工厂
     * @param listenerAdapter 消息适配器，用于消息的分发和处理
     * @return
     */
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                            MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        // 添加 适配器 处理指定topic的消息
        container.addMessageListener(listenerAdapter, new PatternTopic("chat"));

        return container;
    }

    @Bean
    Receiver receiver(CountDownLatch latch) {
        return new Receiver(latch);
    }

    @Bean
    CountDownLatch latch() {
        return new CountDownLatch(1);
    }

    /**
     * 创建RedisTemplate
     * StringRedisTemplate的key-value都是String
     * @param factory
     * @return
     */
    @Bean
    StringRedisTemplate template(RedisConnectionFactory factory) {
        return new StringRedisTemplate(factory);
    }
}
